<!-----------------------------------------------------------------------------
-- Spine Runtimes Software License
-- Version 2.1
-- 
-- Copyright (c) 2013, Esoteric Software
-- All rights reserved.
-- 
-- You are granted a perpetual, non-exclusive, non-sublicensable and
-- non-transferable license to install, execute and perform the Spine Runtimes
-- Software (the "Software") solely for internal use. Without the written
-- permission of Esoteric Software (typically granted by licensing Spine), you
-- may not (a) modify, translate, adapt or otherwise create derivative works,
-- improvements of the Software or develop new applications using the Software
-- or (b) remove, delete, alter or obscure any trademarks or any copyright,
-- trademark, patent or other intellectual property or proprietary rights
-- notices on or in the Software, including any copy thereof. Redistributions
-- in binary or source form must include this license and terms.
-- 
-- THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
-- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-- EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------>

<html>
<head>
<meta charset="UTF-8">
<title>spine-js</title>
<script src="../spine-js/spine.js"></script>
<script src="../turbulenz/turbulenzengine.js"></script>
<script src="../turbulenz/graphicsdevice.js"></script>
<script src="../turbulenz/draw2d.js"></script>
<script src="../SpriteBatch.js"></script>
<style>body, input { font-family: tahoma; font-size: 11pt }</style>
</head>
<body>

<div id="message"></div>
<div><canvas id="canvas" width="640" height="480"/></div>
<br>
<input type="button" value="Spineboy" onclick="load('spineboy')">
<input type="button" value="Goblins" onclick="load('goblins')">
&nbsp; &nbsp; &nbsp; Click above to change the animation (Spineboy) or skin (Goblins).

<script>
var canvas = document.getElementById("canvas");
var TurbulenzEngine = WebGLTurbulenzEngine.create({canvas: canvas});
var graphicsDevice = TurbulenzEngine.createGraphicsDevice({});
var draw2D = Draw2D.create({graphicsDevice: graphicsDevice});

load("spineboy");
//load("goblins");

var skeletonName;
function load (name) {
	skeletonName = name;
	TurbulenzEngine.request("data/" + skeletonName + ".atlas", loadAtlas);
}

var atlas;
function loadAtlas (atlasText) {
	var textureCount = 0;
	atlas = new spine.Atlas(atlasText, {
		load: function (page, path, atlas) {
			textureCount++;
			graphicsDevice.createTexture({
				src: "data/" + path,
				mipmaps: true,
				onload: function (texture) {
					page.rendererObject = texture;
					page.width = texture.width;
					page.height = texture.height;
					atlas.updateUVs(page);
					textureCount--;
				}
			});
		},
		unload: function (texture) {
			texture.destroy();
		}
	});
	function waitForTextures () {
		if (!textureCount)
			TurbulenzEngine.request("data/" + skeletonName + ".json", loadSkeletonData);
		else
			setTimeout(waitForTextures, 100);
	}
	waitForTextures();
}

var skeletonData;
function loadSkeletonData (skeletonText) {
	var json = new spine.SkeletonJson(new spine.AtlasAttachmentLoader(atlas));
	skeletonData = json.readSkeletonData(JSON.parse(skeletonText));
	start();
}

function start () {
	spine.Bone.yDown = true;

	var skeleton = new spine.Skeleton(skeletonData);
	skeleton.x = 320;
	skeleton.y = 440;
	skeleton.updateWorldTransform();

	var stateData = new spine.AnimationStateData(skeletonData);	
	var state = new spine.AnimationState(stateData);

	if (skeletonName == "spineboy") {
		stateData.setMixByName("walk", "jump", 0.2);
		stateData.setMixByName("jump", "walk", 0.4);
		state.setAnimationByName(0, "drawOrder", true);

		canvas.onmousedown = function () {
			state.setAnimationByName(0, "jump", false);
			state.addAnimationByName(0, "walk", true, 0);
		}
	} else {
		skeleton.setSkinByName("goblingirl");
		skeleton.setSlotsToSetupPose();
		state.setAnimationByName(0, "walk", true);

		canvas.onmousedown = function () {
			skeleton.setSkinByName(skeleton.skin.name == "goblin" ? "goblingirl" : "goblin");
			skeleton.setSlotsToSetupPose();
		}
	}
	
	state.onEvent = function (trackIndex, event) {
		// alert(trackIndex + " event: " + event.data.name)
	}

	var bgColor = [0.9, 0.9, 0.9, 1.0];
	var batch = new SpriteBatch(draw2D);
	var lastTime = TurbulenzEngine.time;
	function update() {
		if (!graphicsDevice) return;

		var delta = TurbulenzEngine.time - lastTime;
		lastTime = TurbulenzEngine.time;
		state.update(delta);
		state.apply(skeleton);
		skeleton.updateWorldTransform();

		graphicsDevice.clear(bgColor, 1.0);
		batch.begin(draw2D.blend.alpha);
		drawSkeleton(batch, skeleton);
		batch.end();
		graphicsDevice.endFrame();
	}

	TurbulenzEngine.setInterval(update, 1000 / 60);
}

var vertices = [];
function drawSkeleton (batch, skeleton) {
	var drawOrder = skeleton.drawOrder;
	for (var i = 0, n = drawOrder.length; i < n; i++) {
		var slot = drawOrder[i];
		var attachment = slot.attachment;
		if (!(attachment instanceof spine.RegionAttachment)) continue;
		attachment.computeVertices(skeleton.x, skeleton.y, slot.bone, vertices);
		
		var blendMode = slot.data.additiveBlending ? draw2D.blend.additive : draw2D.blend.alpha;
		if (batch.blendMode != blendMode) {
			batch.end();
			batch.begin(blendMode);
		}

		batch.add(
			attachment.rendererObject.page.rendererObject,
			vertices[0], vertices[1],
			vertices[6], vertices[7],
			vertices[2], vertices[3],
			vertices[4], vertices[5],
			skeleton.r * slot.r,
			skeleton.g * slot.g,
			skeleton.b * slot.b,
			skeleton.a * slot.a,
			attachment.uvs[0], attachment.uvs[1],
			attachment.uvs[4], attachment.uvs[5]
		);
	}
}
</script>

</body>
</html>